/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package gui.animation;

import java.awt.Color;
import java.awt.Point;
import java.awt.geom.Point2D;

import javax.swing.JFrame;

import physics.Circle;
import physics.Rectangle;
import physics.Shape;
import physics.World;

public final class Painter extends Thread {
    
    public static final int DEFAULT_FPS = 30;

    private int fps = DEFAULT_FPS;
    private World scene;
    private Viewport viewport;
    private boolean running;
    private JFrame frame;

    public Painter(World scene, Viewport viewport, JFrame frame) {
        super("Painter thread");
        this.scene = scene;
        this.viewport = viewport;
        this.frame = frame;
    }

    @Override
    public void start() {
        super.start();
        running = true;
    }

    @Override
    public void run() {
        long period = 1000 / fps;
        long before, diff;
        while (running) {
            before = System.currentTimeMillis();

            viewport.update();
            paint(scene, viewport);
            frame.repaint();

            diff = period - (System.currentTimeMillis() - before);
            if (diff > 0) {
                try {
                    Thread.sleep(diff);
                } catch (InterruptedException e) {
                    System.out.println(e);
                }
            }
        }
    }

    public Viewport getViewport() {
        return viewport;
    }
    
    private void paint(World scene, Viewport v) {
    	synchronized(scene) {
    		v.getGraphics().setColor(Color.GRAY);
            v.getGraphics().fillRect(0, 0, v.getImage().getWidth(null), v.getImage().getHeight(null));
        	
	    	for(Shape shape : scene.getWorld()) {
	    		paintItem(shape, v);
	    	}
    	}
    }
    
    private void paintItem(Shape shape, Viewport v) {
    	if(shape.isCircle()) {
    		paintCircle((Circle)shape, v);
    	} else if(shape.isRectangle()) {
    		paintRect((Rectangle)shape, v);
    	}
    }
    
    private void paintCircle(Circle cir, Viewport v) {
        Point2D.Double point = new Point2D.Double(cir.getPosn().x, cir.getPosn().y);
        if (!v.isInBounds(point)) return;
        point.x -= cir.getRadius();
        point.y += cir.getRadius();
        Point pixel = v.getPixel(point);
        int diameter = v.getPixelLength(cir.getRadius() * 2);
        v.getGraphics().setColor(Color.BLUE);
        v.getGraphics().fillOval(pixel.x, pixel.y, diameter, diameter);
    }
    
    private void paintRect(Rectangle rect, Viewport v) {
        Point2D.Double point = new Point2D.Double(rect.getBotLeftPosn().x,
        		rect.getBotLeftPosn().y);
        if (!v.isInBounds(point)) return;
        Point pixel = v.getPixel(point);
        v.getGraphics().setColor(Color.GREEN);
        v.getGraphics().fillRect(pixel.x, pixel.y-(int)rect.getHeight(), 
        		(int)rect.getWidth(), (int)rect.getHeight());
    }
}
